package day05;


import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.support.GenericApplicationContext;

import javax.annotation.PostConstruct;


/**
 * @title: App64_2
 * @author: lbj
 * @date: 2022/5/2 8:42 上午
 * @description: TODO 类描述
 */

/**
 * 解决构造方法循环依赖问题
 */
public class App60_1 {

    static class A{
        private static final Logger log = LoggerFactory.getLogger("A");
//        private B b;

        //解决方式 2 使用对象工厂
//        private ObjectFactory<B> b;
        private ObjectProvider<B> b;

        // 解决方式1 延迟初始化 @Lazy
//        public A(@Lazy B b){
        public A(ObjectProvider<B> b){
            log.debug("A(B b) {}",b.getClass());
            this.b=b;
        }
//        public A(ObjectFactory<B> b){
//            log.debug("A(B b) {}",b.getClass());
//            this.b=b;
//        }

//        public A(B b){
//            log.debug("A(B b) {}",b.getClass());
//            this.b=b;
//        }

        @PostConstruct
        public void init(){
            log.debug("A init()");
        }

//        public void foo(){
//            System.out.println("foo()");
//        }
    }

    static class B{
        private static final Logger log = LoggerFactory.getLogger("B");
        private A a;

        public B(A a){
            log.debug("B(A a) {}",a.getClass());
            this.a = a;
        }

        @PostConstruct
        public void init(){
            log.debug("B init()");
        }
    }

//    @Aspect
//    static class MyAspect{
//        @Before("execution(* foo())")
//        public void before(){
//            System.out.println("before...");
//        }
//    }

    public static void main(String[] args) {
        final GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("a",A.class);
        context.registerBean("b", B.class);

        //测试代理在 3 级缓存中的使用
//        context.registerBean(MyAspect.class);
        context.registerBean(AnnotationAwareAspectJAutoProxyCreator.class);
        AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());
        context.refresh();

//        context.getBean(A.class).foo();
        //解决方式 2 ，bean使用
        System.out.println(context.getBean(A.class).b.getObject());
        System.out.println(context.getBean(B.class));


    }

}
